package com.gongpingjialoan.global;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Build;
import android.support.multidex.MultiDexApplication;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.alibaba.sdk.android.feedback.impl.FeedbackAPI;
import com.alibaba.sdk.android.feedback.util.ErrorCode;
import com.alibaba.sdk.android.feedback.util.FeedbackErrorCallback;
import com.gongpingjialoan.BuildConfig;
import com.gongpingjialoan.activity.main.MainActivity;
import com.gongpingjialoan.api.API;
import com.gongpingjialoan.bean.AppData;
import com.gongpingjialoan.bean.BannerBean;
import com.gongpingjialoan.bean.CarSource;
import com.gongpingjialoan.bean.DataManager;
import com.gongpingjialoan.constant.Const;
import com.gongpingjialoan.data.CategoryData;
import com.gongpingjialoan.data.CityData;
import com.gongpingjialoan.data.UserManager;
import com.gongpingjialoan.network.NetDataJson;
import com.gongpingjialoan.utility.FileUtils;
import com.gongpingjialoan.utility.JSONUtil;
import com.gongpingjialoan.utility.ProcessMonitor;
import com.gongpingjialoan.utility.SharedPreferencesUtil;
import com.gongpingjialoan.utility.UserLocation;
import com.gongpingjialoan.utility.Utils;
import com.google.gson.Gson;
import com.taobao.hotfix.HotFixManager;
import com.taobao.hotfix.PatchLoadStatusListener;
import com.taobao.hotfix.util.PatchStatusCode;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import com.umeng.socialize.PlatformConfig;
import com.xiaomi.mipush.sdk.MiPushClient;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.UUID;
import java.util.concurrent.Callable;


public class GPJApplication extends MultiDexApplication implements NetDataJson.OnNetDataJsonListener {

    private CategoryData mCategoryData = new CategoryData();

    private CityData mCityData = new CityData();

    private JSONObject mHistoryJson = null;

    private CarSource mCarSource;

    private JSONObject mMetaJson = null;

    private JSONArray mBrandJson = null;

    private JSONArray mModelJson = null;

    private JSONArray mCityJson = null;

    private JSONArray mHotBrandJson = null;

    private NetDataJson mNetMetaData;

    private boolean mIsLogin;

    private boolean isregisterlogin = false;

    private UserManager mUserManager = null;

    private String deviceCode = "";

    public String version = "";

    public String chat_user_id = "";

    public boolean isChangeCity = false;


    public CarSource getCarSource() {
        return mCarSource;
    }

    public void setCarSource(CarSource carSource) {
        mCarSource = carSource;
    }

    public String getRootPath() {
        return getApplicationContext().getFilesDir().getAbsolutePath() + "/";
    }

    private static GPJApplication instance;

    public String user_agent = "android";

    public int verison_code;

    public boolean accept_pushing;

    public String app_version;

    public BannerBean mBannerBean;

    public AppData mAppData;

    public String getAppdataStatus = "";

    public String getNotStatus = "";

    public String checkLoginStatus = "";

    public boolean fileDataStatus = true;

    public static GPJApplication getInstance() {
        return instance;
    }

    public IWXAPI wxApi;

    private String data_count = "";

    public String channel = "";

    // user your appid the key.
    private static final String APP_ID = "2882303761517632779";
    // user your appid the key.
    private static final String APP_KEY = "5311763296779";

    public final static String DEFAULT_APPKEY = "23566081";


    public String getData_count() {
        return data_count;
    }

    private void setUser_agent() {
        StringBuilder sb = new StringBuilder();
        sb.append("chefenqi/");
        String versionName = "";
        try {
            String pkName = getPackageName();
            versionName = getPackageManager().getPackageInfo(pkName, 0).versionName;
            verison_code = getPackageManager().getPackageInfo(pkName, 0).versionCode;
        } catch (Exception e) {
        }
        sb.append(versionName);
        sb.append(" (android;android").append(Build.VERSION.RELEASE).append(")");
        user_agent = sb.toString();
        app_version = "C " + versionName;
        version = versionName;
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        ProcessMonitor.detach(this);
    }

    private void initFeedBack(){
        // 自定义ErrorCallback
        FeedbackAPI.addErrorCallback(new FeedbackErrorCallback() {
            @Override
            public void onError(Context context, String errorMessage, ErrorCode code) {
                Toast.makeText(context, "ErrMsg is: " + errorMessage, Toast.LENGTH_SHORT).show();
            }
        });
        // Feedback activity的回调
        FeedbackAPI.addLeaveCallback(new Callable() {
            @Override
            public Object call() throws Exception {
                Log.d("DemoApplication", "custom leave callback");
                return null;
            }
        });
        //建议放在此处做初始化
        FeedbackAPI.init(this, DEFAULT_APPKEY);
    }

    /**
     * 将应用的注册到微信
     */
    private void regToWx() {
        // 通过WXAPIFactory工厂，获取IWXAPI的实例
        wxApi = WXAPIFactory.createWXAPI(this, Const.WX_APP_KEY, true);
        // 将应用的注册到微信
        wxApi.registerApp(Const.WX_APP_KEY);
    }


    @Override
    public void onCreate() {
        super.onCreate();
        Utils.LogD("GPJApplication onCreate ");
        String processName = Utils.getProcessName(this, android.os.Process.myPid());
        //防止执行多次
        if (processName != null) {
            ProcessMonitor.attach(this);
            Utils.LogD("GPJApplication onCreate first");
            PlatformConfig.setSinaWeibo("3480814642", "5bbbf0ae335ca57ba1e3c828f45e8793");
            PlatformConfig.setWeixin("wx63ff0f643d107913", "e07951304f3c39ec7e5f4b4be1b3a276");
            PlatformConfig.setQQZone("1101278018", "LJim2lC0iPJ4EpAa");
            initHotfix();
            boolean defaultProcess = "com.gongpingjialoan".equals(processName);
            if (defaultProcess) {

                //注册小米推送
                if (BuildConfig.LEO_DEBUG) {
                    if ((boolean) SharedPreferencesUtil.get(this, "push_register", true)) {
                        SharedPreferencesUtil.put(this, "push_register", false);
                        MiPushClient.registerPush(this, APP_ID, APP_KEY);
                    }
                } else {
                    MiPushClient.registerPush(this, APP_ID, APP_KEY);
                }
                Log.d("push","------------------------------------"+MiPushClient.getRegId(this));
                //注册阿里百川
                initFeedBack();
                channel = Utils.getAppMetaData(this, "UMENG_CHANNEL");
                // LeakCanary.install(this);
                UserLocation.getInstance().init(getApplicationContext());
             /*   com.gongpingjia.utility.CrashHandler crashHandler = com.gongpingjia.utility.CrashHandler.getInstance();
                crashHandler.init();*/


                if (BuildConfig.LEO_DEBUG) {
                    String domain = (String) SharedPreferencesUtil.get(this, "domain", "");
                    if (!TextUtils.isEmpty(domain)) {
                        NetDataJson.SERVER_DOMAIN = domain;
                    }
                }
                mIsLogin = false;
                instance = this;

                regToWx();
                setUser_agent();
//                getNotification();
                getAppInfoData();
                initData(new FileUtils());
                checkLogin();
                //注册一个监听连接状态的listener

            }
        }
    }


    public void getAppInfoData() {
        NetDataJson netDataJson = new NetDataJson(new NetDataJson.OnStringListener() {
            @Override
            public void onDataJsonError(String errorMessage) {
                getAppdataStatus = "failure";
            }

            @Override
            public void onDataJsonUpdate(String json) {
                Gson gson = new Gson();
                mAppData = gson.fromJson(json, AppData.class);
                if ("success".equals(mAppData.getStatus())) {
                    getAppdataStatus = "success";
                    if (MainActivity.main != null) {
                        if (MainActivity.main.assessmentFragment != null && MainActivity.main.assessmentFragment.isAdded()) {
                            MainActivity.main.assessmentFragment.mHotParamersView.setNums(mAppData.getData().getCar_source_count().getValue());
                        }
                    }
                } else {
                    getAppdataStatus = "failure";
                }
            }
        }, 1);
        netDataJson.setUrl(API.app_info_data);
        netDataJson.request("get");
    }

//    public void getNotification() {
//        NetDataJson netNetDataJson = new NetDataJson(new NetDataJson.OnStringListener() {
//            @Override
//            public void onDataJsonError(String errorMessage) {
//                getNotStatus = "failure";
//            }
//
//            @Override
//            public void onDataJsonUpdate(String json) {
//                Gson gson = new Gson();
//                mBannerBean = gson.fromJson(json, BannerBean.class);
//                if ("success".equals(mBannerBean.getStatus())) {
//                    EventBus.getDefault().post("notification");
//                    getNotStatus = "success";
//                } else {
//                    getNotStatus = "failure";
//                }
//            }
//        }, 1);
//        netNetDataJson.setUrl(API.getBanner);
//        netNetDataJson.request("get");
//    }


    public void checkLogin() {
        mUserManager = new UserManager(this);
        Utils.LogD("checkLogin begin ");
        mUserManager.CheckLogin(new UserManager.OnCheckLoginResponse() {
            @Override
            public void onCheckLoginSuccess() {
                checkLoginStatus = "success";
                EventBus.getDefault().post("checklogin");
                Utils.LogD("checkLogin onCheckLoginSuccess ");
            }

            @Override
            public void onCheckLoginError(final String errorMessage) {
                checkLoginStatus = "failure";
                Utils.LogD("checkLogin onCheckLoginError");
                EventBus.getDefault().post("checklogin");
            }
        });

    }


    //获取设备号
    private String getDevice_Code() {
        String uniqueId = "";
        try {
            final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
            final String tmDevice, tmSerial, androidId;
            tmDevice = "" + tm.getDeviceId();
            tmSerial = "" + tm.getSimSerialNumber();
            androidId =
                    ""
                            + android.provider.Settings.Secure.getString(getContentResolver(),
                            android.provider.Settings.Secure.ANDROID_ID);
            UUID deviceUuid = new UUID(androidId.hashCode(), ((long) tmDevice.hashCode() << 32) | tmSerial.hashCode());
            uniqueId = deviceUuid.toString();

            Utils.LogD("uniqueId = " + uniqueId);
        } catch (Exception e) {
            Utils.LogE("获取机器码异常：" + e.getMessage());
        }
        return uniqueId;
    }

    public void initData(FileUtils fileUtils) {
        mNetMetaData = new NetDataJson(GPJApplication.this);
        mNetMetaData.setUrl("/mobile/api/meta-data/");
        mNetMetaData.request("get");

        mBrandJson = fileUtils.readFile2JsonArray(getRootPath(), "mobile_brands");
        if (null != mBrandJson) {
            mCategoryData.LoadBrandData(mBrandJson);
            DataManager.getInstance().setBrandSuccess(true);
            DataManager.getInstance().setIsBrandloading(false);
        }
        mHotBrandJson = fileUtils.readFile2JsonArray(getRootPath(), "mobile_hot_brands");
        if (null != mHotBrandJson) {
            mCategoryData.LoadHotBrandData(mHotBrandJson);
            DataManager.getInstance().setHotBrandSuccess(true);
            DataManager.getInstance().setIsHotBrandlaoding(false);
        }

        mModelJson = fileUtils.readFile2JsonArray(getRootPath(), "mobile_models");
        if (null != mModelJson) {
            mCategoryData.LoadModelData(mModelJson);
            DataManager.getInstance().setModelSuccess(true);
            DataManager.getInstance().setIsModellaoding(false);
        }

        mCityJson = fileUtils.readFile2JsonArray(getRootPath(), "city");
        if (null != mCityJson) {
            mCityData.LoadCityData(mCityJson);
            mCityData.LoadCityData1(mCityJson);
            DataManager.getInstance().setCitySuccess(true);
            DataManager.getInstance().setIsCitylaoding(false);
        }

        mHistoryJson = fileUtils.readFile2JsonObject(getRootPath(), "log");

        if (null == mHistoryJson) {
            try {
                mHistoryJson = new JSONObject();
                JSONArray loglist = new JSONArray();
                mHistoryJson.put("count", 0);
                mHistoryJson.put("loglist", loglist);
            } catch (JSONException e) {

            }
        }
    }

    public String getDeviceCode() {
        if (TextUtils.isEmpty(deviceCode)) {
            deviceCode = getDevice_Code();
        }
        return deviceCode;
    }

    public void setDeviceCode(String deviceCode) {
        this.deviceCode = deviceCode;
    }

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }


    public boolean isLogin() {
        return mIsLogin;
    }

    public void setIslogin(boolean isLogin) {
        this.mIsLogin = isLogin;
    }

    public CategoryData getCategoryData() {
        if (mCategoryData == null) mCategoryData = new CategoryData();
        return mCategoryData;
    }

    public CityData getCityData() {
        return mCityData;
    }

    public JSONObject getMeta() {
        return mMetaJson;
    }

    public boolean isIsregisterlogin() {
        return isregisterlogin;
    }

    public void setIsregisterlogin(boolean isregisterlogin) {
        this.isregisterlogin = isregisterlogin;
    }

    public String getApiUrlFromMeta(String name) {
        String url = "/img/logo/";
        if (null == mMetaJson) {
            return url;
        }
        try {
            JSONArray meta = mMetaJson.getJSONArray("meta_data");

            for (int i = 0; i < meta.length(); i++) {
                if (name.equals(meta.getJSONObject(i).getString("name"))) {
                    url = meta.getJSONObject(i).getString("url");
                }
            }
        } catch (JSONException e) {
        }
        return url;
    }

    public JSONObject getDataFromMeta(String name) {
        if (null == mMetaJson) {
            return null;
        }
        JSONObject jo = null;
        try {
            JSONArray meta = mMetaJson.getJSONArray("meta_data");

            for (int i = 0; i < meta.length(); i++) {
                if (name.equals(meta.getJSONObject(i).getString("name"))) {
                    jo = meta.getJSONObject(i);
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return jo;
    }

    public String getSecert(){
        String secert = JSONUtil.getString(getDataFromMeta("mobile_captcha_action"),"extra_data");
        if(TextUtils.isEmpty(secert)){
            if (SharedPreferencesUtil.contains(getApplicationContext(),secert)){
                secert = (String) SharedPreferencesUtil.get(getApplicationContext(),"secert","");
                if (TextUtils.isEmpty(secert)){
                    secert = "KzKwdx5Mv8Gzx^%OoLZS*lWbkEPmQ$mg";
                }
            }else {
                secert = "KzKwdx5Mv8Gzx^%OoLZS*lWbkEPmQ$mg";
            }
        }else {
            SharedPreferencesUtil.put(getApplicationContext(),"secert",secert);
        }
        return secert;
    }

    public String getPassed(){
       if (mAppData != null){
           return mAppData.getData().getCfq_current_review_version().getValue();
       }
       return null;
    }


    @Override
    public void onDataJsonUpdate(JSONObject json) {

        if (json == null) {
            fileDataStatus = false;
            return;
        }

        if (json.has("meta_data")) {
            mMetaJson = json;
            try {
                data_count = mMetaJson.getString("data_count");
                accept_pushing = mMetaJson.getBoolean("accept_pushing");
            } catch (JSONException e) {
                data_count = "";
            }
            SharedPreferences sharedPreferences = getSharedPreferences("db", Context.MODE_PRIVATE);
            JSONObject condition_detail_optionJo = getDataFromMeta("condition_detail_option");
            JSONObject condition_detail_itemJo = getDataFromMeta("condition_detail_item");
            try {
                if (condition_detail_optionJo != null && condition_detail_itemJo != null) {
                    int optiontime = condition_detail_optionJo.getInt("timestamp");
                    int itemtime = condition_detail_itemJo.getInt("timestamp");
                    int local_option_time = sharedPreferences.getInt("local_option_time", 0);
                    int local_item_time = sharedPreferences.getInt("local_item_time", 0);
                    int version = sharedPreferences.getInt("version", 0);
                    if (local_option_time < optiontime || local_item_time < itemtime || version != Const.DBVersion) {
                        Editor edit = sharedPreferences.edit();
                        edit.putInt("local_option_time", optiontime);
                        edit.putInt("local_item_time", itemtime);
                        edit.putInt("version", Const.DBVersion);
                        edit.commit();
                    }
                }

                JSONObject brand_json = getDataFromMeta("brand_json");
                if (brand_json != null) {
                    int brandtime = brand_json.getInt("timestamp");
                    int local_brand_time = sharedPreferences.getInt("local_brand_time", 0);
                    if (local_brand_time < brandtime) {
                        DataManager.getInstance().getBrandData(mCategoryData,
                                getRootPath(),
                                getApplicationContext(),
                                brandtime);
                    }
                }

                JSONObject model_json = getDataFromMeta("model_json");
                if (model_json != null) {
                    int modeltime = model_json.getInt("timestamp");
                    int local_model_time = sharedPreferences.getInt("local_model_time", 0);
                    if (local_model_time < modeltime) {
                        DataManager.getInstance().getModelData(mCategoryData,
                                getRootPath(),
                                getApplicationContext(),
                                modeltime);
                    }
                }

                JSONObject hot_brand = getDataFromMeta("hot_brand");
                if (hot_brand != null) {
                    int hottime = hot_brand.getInt("timestamp");
                    int local_hot_time = sharedPreferences.getInt("local_hot_time", 0);
                    if (local_hot_time < hottime) {
                        DataManager.getInstance().getHotBrandData(mCategoryData,
                                getRootPath(),
                                getApplicationContext(),
                                hottime);
                    }
                }

                JSONObject city_json = getDataFromMeta("city_json");
                if (city_json != null) {
                    int citytime = city_json.getInt("timestamp");
                    int local_city_time = sharedPreferences.getInt("local_city_time", 0);
                    if (local_city_time < citytime) {
                        DataManager.getInstance().getCityData(mCityData,
                                getRootPath(),
                                getApplicationContext(),
                                citytime);
                    }
                }

            } catch (JSONException e) {
                fileDataStatus = false;
            }

        }

    }

    @Override
    public void onDataJsonError(String errorMessage) {
        fileDataStatus = false;
        Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT).show();
        this.onTerminate();
    }


    /**
     * 建议在Application.onCreate方法中执行initialize和queryNewHotPatch操作, 尽可能早的执行
     * 本demo只是为了测试的方便, 所以把这两个操作放在了Activity中
     */
    private void initHotfix() {
        String appVersion = "";
        try {
            appVersion = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;
        } catch (Exception e) {
            appVersion = "1.0.0";
        }
        //此处不再需要调用queryNewHotPatch方法, initialize方法内部会调用queryNewHotPatch方法.
        HotFixManager.getInstance().setContext(this)
                .setAppVersion(appVersion)
                .setAppId("81957-1")
                .setAesKey(null)
                .setSupportHotpatch(true)
                .setEnableDebug(true)
                .setPatchLoadStatusStub(new PatchLoadStatusListener() {
                    @Override
                    public void onload(final int mode, final int code, final String info, final int handlePatchVersion) {
                        // 补丁加载回调通知
                        if (code == PatchStatusCode.CODE_SUCCESS_LOAD) {
                            Utils.LogD("补丁加载成功");
                            // TODO: 10/24/16 表明补丁加载成功
                        } else if (code == PatchStatusCode.CODE_ERROR_NEEDRESTART) {
                            Utils.LogD("补丁生效需要重启. 业务方可自行实现逻辑");
                            // TODO: 10/24/16 表明新补丁生效需要重启. 业务方可自行实现逻辑, 提示用户或者强制重启, 建议: 用户可以监听进入后台事件, 然后应用自杀
                        } else if (code == PatchStatusCode.CODE_ERROR_INNERENGINEFAIL) {
                            Utils.LogD("内部引擎加载异常");
                            // 内部引擎加载异常, 推荐此时清空本地补丁, 但是不清空本地版本号, 防止失败补丁重复加载
                           HotFixManager.getInstance().cleanPatches(false);
                        } else {
                            Utils.LogD("code-->" + code);
                            // TODO: 10/25/16 其它错误信息, 查看PatchStatusCode类说明
                        }
                    }
                }).initialize();
    }

}
